/* * This file is part of CBCJVM. * CBCJVM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CBCJVM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CBCJVM. If not, see <http://www.gnu.org/licenses/>. */ package cbc.helpers; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; import org.eclipse.jface.dialogs.MessageDialog; /** * * @author Braden McDorman * */ public class Ssh { JSch jsch = new JSch(); Session session = null; String user; String ip; String hosts = System.getProperty("user.home") + File.separatorChar; public Ssh(String user, String ip) throws IOException { if (File.separatorChar == '\\') { // Winblows doesn't like periods hosts += "ssh"; } else { hosts += ".ssh"; } new File(hosts).mkdirs(); hosts += File.separatorChar + "known_hosts"; this.user = user; this.ip = ip; if (!checkIp(ip)) { throw new IOException( "IPv4 Address is an invalid format! Must be: [0-255].[0-255].[0-255].[0-255]"); } try { // Establish connection session = jsch.getSession(user, ip, 22); File known_hosts = new File(hosts); known_hosts.createNewFile(); String absolute = known_hosts.getAbsolutePath(); jsch.setKnownHosts(absolute); MyUserInfo ui = new MyUserInfo(); session.setUserInfo(ui); session.connect(); } catch (JSchException e) { throw new IOException(e.toString()); } catch (IOException e) { throw new IOException(e.toString()); } catch (Exception e) { throw new IOException(e.toString()); } } public static boolean checkIp(String sip) { String[] parts = sip.split("\\."); for (String s : parts) { int i = Integer.parseInt(s); if (i < 0 || i > 255) { return false; } } return true; } public void sendFile(String path, File toSend) throws IOException { // Start remote scp String command = "scp -p -t " + path; Channel channel = null; try { channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); OutputStream out = channel.getOutputStream(); InputStream in = channel.getInputStream(); channel.connect(); int check = checkAck(in); if (check != 0) { throw new IOException( "CheckAck failed when starting remote scp (" + check + ")"); } // Send file properties long filesize = toSend.length(); command = "C0644 " + filesize + " "; command += toSend.getName(); command += "\n"; System.out.print(command); out.write(command.getBytes()); out.flush(); check = checkAck(in); if (check != 0) { throw new IOException( "CheckAck failed when sending file properties (" + check + ")"); } // Send file FileInputStream fis = new FileInputStream(toSend); byte[] buf = new byte[1024]; while (true) { int len = fis.read(buf, 0, buf.length); if (len <= 0) break; out.write(buf, 0, len); } fis.close(); fis = null; buf[0] = 0; out.write(buf, 0, 1); out.flush(); check = checkAck(in); if (check != 0) { throw new IOException( "CheckAck failed when sending file data (" + check + ")"); } // Cleanup out.close(); channel.disconnect(); } catch (JSchException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public int sendCommand(String command) { int ret = -1; try { Channel channel = session.openChannel("exec"); ((ChannelExec) channel).setCommand(command); channel.setInputStream(null); ((ChannelExec) channel).setErrStream(System.err); InputStream in = channel.getInputStream(); channel.connect(); byte[] tmp = new byte[1024]; while (true) { while (in.available() > 0) { int i = in.read(tmp, 0, 1024); if (i < 0) break; System.out.print(new String(tmp, 0, i)); } if (channel.isClosed()) { ret = channel.getExitStatus(); break; } try { Thread.sleep(1000); } catch (Exception ee) { } } channel.disconnect(); } catch (JSchException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return ret; } public void close() { session.disconnect(); } int checkAck(InputStream in) throws IOException { int b = in.read(); if (b == 0) return b; if (b == -1) return b; if (b == 1 || b == 2) { StringBuffer sb = new StringBuffer(); int c; do { c = in.read(); sb.append((char) c); } while (c != '\n'); if (b == 1) { // error System.out.print(sb.toString()); } if (b == 2) { // fatal error System.out.print(sb.toString()); } } return b; } public static class MyUserInfo implements UserInfo, UIKeyboardInteractive { public String getPassword() { return passwd; } public boolean promptYesNo(String str) { MessageDialog dialog = new MessageDialog(null, "CBC Plug-in", null, str, MessageDialog.QUESTION, new String[] { "Yes", "No" }, 0); // yes is the default int result = dialog.open(); return result == 0; } String passwd; JTextField passwordField = (JTextField) new JPasswordField(20); public String getPassphrase() { return null; } public boolean promptPassphrase(String message) { return true; } public boolean promptPassword(String message) { Object[] ob = { passwordField }; int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION); if (result == JOptionPane.OK_OPTION) { passwd = passwordField.getText(); return true; } else { return false; } } public void showMessage(String message) { JOptionPane.showMessageDialog(null, message); } final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0); private Container panel; public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, boolean[] echo) { panel = new JPanel(); panel.setLayout(new GridBagLayout()); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridx = 0; panel.add(new JLabel(instruction), gbc); gbc.gridy++; gbc.gridwidth = GridBagConstraints.RELATIVE; JTextField[] texts = new JTextField[prompt.length]; for (int i = 0; i < prompt.length; i++) { gbc.fill = GridBagConstraints.NONE; gbc.gridx = 0; gbc.weightx = 1; panel.add(new JLabel(prompt[i]), gbc); gbc.gridx = 1; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 1; if (echo[i]) { texts[i] = new JTextField(20); } else { texts[i] = new JPasswordField(20); } panel.add(texts[i], gbc); gbc.gridy++; } if (JOptionPane.showConfirmDialog(null, panel, destination + ": " + name, JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) { String[] response = new String[prompt.length]; for (int i = 0; i < prompt.length; i++) { response[i] = texts[i].getText(); } return response; } else { return null; // cancel } } } }